package bot.module.th.shc;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

import static util.poker.texas.BetInt.*;
/** http://ostermiller.org/utils/CSV.html */
import com.Ostermiller.util.CSVParser;

/**
 * CSV startinghandchart </br>
 * custom table by importing own csv file </br>
 * 
 * @author Witthold/Korol
 */
public class TableCSV extends StartingHandChart {

	private static final String csvPath = "bin/bot/module/th/shc/data/";

	/** table wants the 5 standard position classes 0-4 */
	private static final int numPosition = 5;
	/** table offers 0-4 Calls */
	private static final int numCalls = 5;
	/** table offers 0-3 Raises */
	private static final int numRaises = 4;
	/** helper Array to store csv data temporary - card rows * numPosition * numCalls * numRaises */
	int[][][][] csvArr = new int[127][numPosition][numCalls][numRaises];


	/**
	 * Constructor calls super of StartingHandChart </br>
	 * 
	 * @param csvDat - myTable.csv
	 */
	public TableCSV(String csvDat) {
		super(numPosition, numCalls, numRaises);

		csvArr = importCSV(csvPath + csvDat + ".csv");
		createTable();
		fixTable();
	}


	/**
	 * parses csv file
	 * 
	 * @param csv_dat - myTable.csv
	 * @return int[][][][] - helper Array to store csv data temporary - card rows * (position*numCalls*numRaises)
	 */
	private int[][][][] importCSV(String csvDat) {

		CSVParser csvParser;
		try {
			csvParser = new CSVParser(new FileInputStream(csvDat));

			int ln = 0; // lineNumber
			int p = 0;
			int c = 0;
			int r = 0;

			for (String s; (s = csvParser.nextValue()) != null;) {
				ln = csvParser.lastLineNumber() - 1;

				//DebugOut.showVerboseShc(ln + "," + sp + "," + c + "," + r + ": " + s);

				csvArr[ln][p][c][r] = betStringToInt(s);

				/* consider position, calls, raises */
				if (p < numPosition - 1) {
					p++;
				} else {
					p = 0;
					if (c < numCalls - 1) {
						c++;
					} else {
						/*
						 * consider: raises egalizes calls,
						 * so: raises>0 => calls = numCalls-1
						 * @see fixTable()
						 */
						//c = 0;
						if (r < numRaises - 1) {
							r++;
						} else {
							c = 0;
							r = 0;
						}
					}
				}
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

		return csvArr;
	}


	/**
	 * converts csv's String to int
	 * 
	 * @param s - String from csv (e.g. "RAISE4")
	 * @return appropriate int representation, a "NA"/"-2" should not appear by getBet()
	 */
	private int betStringToInt(String s) {
		int i = -2;
		if (s.equals("F")) {
			return FOLD;
		} else if (s.equals("CHECK")) {
			return CHECK;
		} else if (s.equals("CALL")) {
			return CALL;
		} else if (s.equals("CALL20")) {
			return CALL20;
		} else if (s.equals("RAISE3")) {
			return RAISE3;
		} else if (s.equals("RAISE4")) {
			return RAISE4;
		} else if (s.equals("ALLIN")) {
			//DebugOut.showVerboseShc("TableCSV.betStringToInt:ALLIN: " + ALLIN);
			return ALLIN;
		} else if (s.equals("NA")) {
			return NA;
		}
		System.err.println("ERROR.TableCSV.betStringToInt: Wrong value of s: " + s);
		return i;
	}


	/**
	 * fills the table in defined order from helperArray
	 */
	private void createTable() {

		/**
		 * sections lengths of csv </br>
		 * consider table human style, csvArr machine style </br>
		 * so add 2 to csvArr index
		 */
		int pairs = 12;
		int aces = 24;
		int kings = 22;
		int queens = 20;
		int jacks = 18;
		int tens = 16;
		int conns = 14;

		for (int r1 = 2; r1 < table.length; r1++) {
			for (int s1 = 0; s1 < table[0].length; s1++) {
				for (int r2 = 2; r2 < table[0][0].length; r2++) {
					for (int s2 = 0; s2 < table[0][0][0].length; s2++) {
						for (int p = 0; p < table[0][0][0][0].length; p++) {
							for (int c = 0; c < table[0][0][0][0][0].length; c++) {
								for (int r = 0; r < table[0][0][0][0][0][0].length; r++) {
									/**
									 * conditions by csv structure *
									 */
									/**
									 * Pairs: 2-14 respectively 0-12
									 */
									if (r1 == r2) {
										table[r1][s1][r2][s2][p][c][r] = csvArr[pairs - r1 + 2][p][c][r];
									}
									/**
									 * Ace combinations
									 */
									if (r1 == 14 && r2 != 14) {
										/** card1 */
										if (s1 == s2) {
											/** suited */
											table[r1][s1][r2][s2][p][c][r] = csvArr[pairs + aces / 2 - r2 + 2][p][c][r];
										} else {
											/** unsuited */
											table[r1][s1][r2][s2][p][c][r] = csvArr[pairs + aces - r2 + 2][p][c][r];
										}
									} else if (r1 != 14 && r2 == 14) {
										/** card2 */
										if (s1 == s2) {
											/** suited */
											table[r1][s1][r2][s2][p][c][r] = csvArr[pairs + aces / 2 - r1 + 2][p][c][r];
										} else {
											/** unsuited */
											table[r1][s1][r2][s2][p][c][r] = csvArr[pairs + aces - r1 + 2][p][c][r];
										}
									}
									/**
									 * King combinations
									 */
									else if (r1 == 13 && r2 != 13) {
										/** card1 */
										if (s1 == s2) {
											/** suited */
											table[r1][s1][r2][s2][p][c][r] = csvArr[pairs + aces + kings / 2 - r2 + 2][p][c][r];
										} else {
											/** unsuited */
											table[r1][s1][r2][s2][p][c][r] = csvArr[pairs + aces + kings - r2 + 2][p][c][r];
										}
									} else if (r1 != 13 && r2 == 13) {
										/** card2 */
										if (s1 == s2) {
											/** suited */
											table[r1][s1][r2][s2][p][c][r] = csvArr[pairs + aces + kings / 2 - r1 + 2][p][c][r];
										} else {
											/** unsuited */
											table[r1][s1][r2][s2][p][c][r] = csvArr[pairs + aces + kings - r1 + 2][p][c][r];
										}
									}
									/**
									 * Queen combinations
									 */
									else if (r1 == 12 && r2 != 12) {
										/** card1 */
										if (s1 == s2) {
											/** suited */
											table[r1][s1][r2][s2][p][c][r] = csvArr[pairs + aces + kings + queens / 2 - r2 + 2][p][c][r];
										} else {
											/** unsuited */
											table[r1][s1][r2][s2][p][c][r] = csvArr[pairs + aces + kings + queens - r2 + 2][p][c][r];
										}
									} else if (r1 != 12 && r2 == 12) {
										/** card2 */
										if (s1 == s2) {
											/** suited */
											table[r1][s1][r2][s2][p][c][r] = csvArr[pairs + aces + kings + queens / 2 - r1 + 2][p][c][r];
										} else {
											/** unsuited */
											table[r1][s1][r2][s2][p][c][r] = csvArr[pairs + aces + kings + queens - r1 + 2][p][c][r];
										}
									}
									/**
									 * Jack combinations
									 */
									else if (r1 == 11 && r2 != 11) {
										/** card1 */
										if (s1 == s2) {
											/** suited */
											table[r1][s1][r2][s2][p][c][r] = csvArr[pairs + aces + kings + queens + jacks / 2 - r2 + 2][p][c][r];
										} else {
											/** unsuited */
											table[r1][s1][r2][s2][p][c][r] = csvArr[pairs + aces + kings + queens + jacks - r2 + 2][p][c][r];
										}
									} else if (r1 != 11 && r2 == 11) {
										/** card2 */
										if (s1 == s2) {
											/** suited */
											table[r1][s1][r2][s2][p][c][r] = csvArr[pairs + aces + kings + queens + jacks / 2 - r1 + 2][p][c][r];
										} else {
											/** unsuited */
											table[r1][s1][r2][s2][p][c][r] = csvArr[pairs + aces + kings + queens + jacks - r1 + 2][p][c][r];
										}
									}
									/**
									 * Ten combinations
									 */
									else if (r1 == 10 && r2 != 10) {
										/** card1 */
										if (s1 == s2) {
											/** suited */
											table[r1][s1][r2][s2][p][c][r] = csvArr[pairs + aces + kings + queens + jacks + tens / 2 - r2 + 2][p][c][r];
										} else {
											/** unsuited */
											table[r1][s1][r2][s2][p][c][r] = csvArr[pairs + aces + kings + queens + jacks + tens - r2 + 2][p][c][r];
										}
									} else if (r1 != 10 && r2 == 10) {
										/** card2 */
										if (s1 == s2) {
											/** suited */
											table[r1][s1][r2][s2][p][c][r] = csvArr[pairs + aces + kings + queens + jacks + tens / 2 - r1 + 2][p][c][r];
										} else {
											/** unsuited */
											table[r1][s1][r2][s2][p][c][r] = csvArr[pairs + aces + kings + queens + jacks + tens - r1 + 2][p][c][r];
										}
									}
									/**
									 * Connectors (lower than Ten)
									 */
									else if ((r1 - r2 == 1) && r1 < 10) {
										/** card1 */
										if (s1 == s2) {
											/** suited */
											table[r1][s1][r2][s2][p][c][r] = csvArr[pairs + aces + kings + queens + jacks + tens + conns / 2 - r2 + 2][p][c][r];
										} else {
											/** unsuited */
											table[r1][s1][r2][s2][p][c][r] = csvArr[pairs + aces + kings + queens + jacks + tens + conns - r2 + 2][p][c][r];
										}
									} else if ((r1 - r2 == -1) && r2 < 10) {
										/** card2 */
										if (s1 == s2) {
											/** suited */
											table[r1][s1][r2][s2][p][c][r] = csvArr[pairs + aces + kings + queens + jacks + tens + conns / 2 - r1 + 2][p][c][r];
										} else {
											/** unsuited */
											table[r1][s1][r2][s2][p][c][r] = csvArr[pairs + aces + kings + queens + jacks + tens + conns - r1 + 2][p][c][r];
										}
									}
								}
							}
						}
					}
				}
			}
		}
	}


	/**
	 * correct priority of raises over calls into table
	 */
	private void fixTable() {
		for (int r1 = 2; r1 < table.length; r1++) {
			for (int s1 = 0; s1 < table[0].length; s1++) {
				for (int r2 = 2; r2 < table[0][0].length; r2++) {
					for (int s2 = 0; s2 < table[0][0][0].length; s2++) {
						for (int p = 0; p < table[0][0][0][0].length; p++) {
							for (int c = 0; c < table[0][0][0][0][0].length - 1; c++) {
								for (int r = 1; r < table[0][0][0][0][0][0].length; r++) {
									table[r1][s1][r2][s2][p][c][r] = table[r1][s1][r2][s2][p][4][r];
								}
							}
						}
					}
				}
			}
		}
	}
}
